library(scPipe)
library(scater)
library(scran)
library(ggplot2)
library(Seurat)
library(cowplot)
library(sctransform)
library(dplyr)
library(readr)
library(ggrepel)
library(RColorBrewer)
getPalette = colorRampPalette(brewer.pal(9, "Set1"))
col9 = getPalette(9)
ttt = col9[5]
col9[5] = col9[1]
col9[1] = ttt
load("~/Dropbox/research/Dach1_paper/NN126/NN126_Seurat_analysis.RData")
s.genes <- tolower(cc.genes$s.genes)
g2m.genes <- tolower(cc.genes$g2m.genes)
simpleCap <- function(x) {
paste(toupper(substring(x, 1,1)), substring(x, 2),
sep="")
}
s.genes = simpleCap(s.genes)
g2m.genes = simpleCap(g2m.genes)
srt_filter_cc = srt_combine_filter
srt_filter_cc <- CellCycleScoring(srt_filter_cc, s.features = s.genes, g2m.features = g2m.genes, set.ident = FALSE)
head(srt_filter_cc[[]])
RidgePlot(srt_filter_cc, features = c("Pcna", "Top2a", "Mcm6", "Mki67"), ncol = 2,cols=getPalette(7))
Picking joint bandwidth of 0.14
Picking joint bandwidth of 0.158
Picking joint bandwidth of 0.171
Picking joint bandwidth of 0.179

DimPlot(srt_filter_cc, reduction = "umap", group.by = "Phase")

srt_filter_cc <- ScaleData(srt_filter_cc, vars.to.regress = c("S.Score", "G2M.Score"), features = rownames(srt_filter_cc),verbose = FALSE)
srt_filter_cc <- RunPCA(object = srt_filter_cc, verbose = FALSE)
srt_filter_cc <- RunUMAP(object = srt_filter_cc, dims = 1:15, verbose = FALSE)
srt_filter_cc <- FindNeighbors(object = srt_filter_cc, k.param=10, dims = 1:15, verbose = FALSE)
srt_filter_cc <- FindClusters(object = srt_filter_cc, verbose = FALSE,resolution = 1.2)
# Visualization
p1 <- DimPlot(srt_filter_cc, reduction = "umap", group.by = "Phase")
p2 <- DimPlot(srt_filter_cc, reduction = "umap", label = TRUE, cols=col9)
plot_grid(p1, p2)

srt_filter_cc.markers <- FindAllMarkers(srt_filter_cc, logfc.threshold = 0.1,only.pos = TRUE,verbose=FALSE)
top10 <- srt_filter_cc.markers %>% group_by(cluster) %>% top_n(n = 10, wt = avg_logFC)
DoHeatmap(srt_filter_cc, features = top10$gene) # cannot change color of the color bar

VlnPlot(object = srt_filter_cc, features= c("Dach1GFP","CD150","CD135","CD127","cKit"), cols=col9, ncol=2,pt.size=0.1)

FeaturePlot(object = srt_filter_cc, cols =rev(rainbow(5))[2:5],features =c("Dach1GFP","CD11b","CD150","CD127","cKit","CD135","Sca1","PI"), pt.size =1)

p1=ggplot(data=NULL,aes(x=srt_filter_cc@meta.data$CD135,y=srt_filter_cc@meta.data$CD150,col=srt_filter_cc@active.ident))+
geom_point(alpha=0.7,size=1.5)+
labs(x="CD135",y="CD150",col="cluster")+
scale_color_manual(values=col9)+
theme_bw()
p2=ggplot(data=NULL,aes(x=srt_filter_cc@meta.data$Dach1GFP,y=srt_filter_cc@meta.data$CD135,col=srt_filter_cc@active.ident))+
geom_point(alpha=0.7,size=1.5)+
scale_color_manual(values=col9)+
labs(x="Dach1GFP",y="CD135",col="cluster")+
theme_bw()
p3=ggplot(data=NULL,aes(x=srt_filter_cc@meta.data$cKit,y=srt_filter_cc@meta.data$Sca1,col=srt_filter_cc@active.ident))+
geom_point(alpha=0.7,size=1.5)+
scale_color_manual(values=col9)+
labs(x="cKit",y="Sca1",col="cluster")+
theme_bw()
p4=ggplot(data=NULL,aes(x=srt_filter_cc@meta.data$CD135,y=srt_filter_cc@meta.data$CD127,col=srt_filter_cc@active.ident))+
geom_point(alpha=0.7,size=1.5)+
scale_color_manual(values=col9)+
labs(x="CD135",y="CD127",col="cluster")+
theme_bw()
plot_grid(p1, p2, p3, p4,ncol=2)

trajectory
# BiocManager::install("supraHex")
# BiocManager::install("Rgraphviz")
library(XGR)
package ‘XGR’ was built under R version 3.5.2Loading required package: igraph
Attaching package: ‘igraph’
The following object is masked from ‘package:scater’:
normalize
The following objects are masked from ‘package:DelayedArray’:
path, simplify
The following object is masked from ‘package:GenomicRanges’:
union
The following object is masked from ‘package:IRanges’:
union
The following object is masked from ‘package:S4Vectors’:
union
The following objects are masked from ‘package:BiocGenerics’:
normalize, path, union
The following object is masked from ‘package:tidyr’:
crossing
The following objects are masked from ‘package:dplyr’:
as_data_frame, groups, union
The following objects are masked from ‘package:stats’:
decompose, spectrum
The following object is masked from ‘package:base’:
union
Loading required package: dnet
Loading required package: supraHex
Loading required package: hexbin
x = xConverter(srt_filter_cc@graphs$integrated_snn, from = "dgCMatrix",
to ="igraph",verbose = FALSE)
ggplotColours <- function(n = 6, h = c(0, 360) + 15){
if ((diff(h) %% 360) < 1) h[2] <- h[2] - 360/n
hcl(h = (seq(h[1], h[2], length = n)), c = 100, l = 65)
}
library(igraph)
set.seed(19910603)
l <- layout_with_fr(x,dim=2,niter=2000,start.temp=500)
plot(x, layout=l, vertex.label=NA,vertex.size=3,vertex.color=srt_filter_cc$integrated_snn_res.1.2,palette=col9)

library(slingshot)
sls = slingshot(l, clusterLabels = srt_filter_cc$integrated_snn_res.1.2,start.clus=1)
Using full covariance matrix
plot(l, col=col9[srt_filter_cc$integrated_snn_res.1.2], pch=16, asp = 1)
lines(sls, lwd=2, col='black')

top2 <- srt_filter_cc.markers %>% group_by(cluster) %>% top_n(n = 2, wt = avg_logFC)
DotPlot(srt_filter_cc, features = c(top2$gene,"CD135","Dach1GFP")) + RotatedAxis()
Error in `levels<-`(`*tmp*`, value = as.character(levels)) :
factor level [20] is duplicated
LPP LMPP
LPP = rep(FALSE,length(srt_filter_cc@active.ident))
LPP[srt_filter_cc@active.ident==4] = TRUE
CD135_hi_thr = 3.
CD135_very_hi_thr = 3.5
Dach1_thr = 2.8
p1=ggplot(data=NULL,aes(x=srt_filter_cc@meta.data$CD135,y=srt_filter_cc@meta.data$CD150,col=LPP))+
geom_point(alpha=0.5,size=1)+
geom_vline(xintercept = CD135_very_hi_thr,linetype="dotted")+
geom_vline(xintercept = CD135_hi_thr,linetype="dotted")+
geom_text(aes(x=CD135_hi_thr, label="LMPP\n", y=2.7), colour="blue", angle=90, text=element_text(size=11))+
geom_text(aes(x=CD135_very_hi_thr, label="CD135++\n", y=2.7), colour="blue", angle=90, text=element_text(size=11))+
scale_color_manual(values=c("grey70","red"))+
labs(x="CD135",y="CD150",col="cluster")+
theme_bw()
Ignoring unknown parameters: textIgnoring unknown parameters: text
p2=ggplot(data=NULL,aes(x=srt_filter_cc@meta.data$Dach1GFP,y=srt_filter_cc@meta.data$CD135,col=LPP))+
geom_point(alpha=0.5,size=1)+
geom_vline(xintercept = Dach1_thr,linetype="dotted")+
geom_text(aes(x=Dach1_thr, label="Dach1-\n", y=3.5), colour="blue", angle=90, text=element_text(size=11))+
geom_hline(yintercept = CD135_hi_thr,linetype="dotted")+
geom_text(aes(y=CD135_hi_thr, label="LMPP\n", x=2.5), colour="blue", text=element_text(size=11))+
scale_color_manual(values=c("grey70","red"))+
labs(x="Dach1GFP",y="CD135",col="cluster")+
theme_bw()
Ignoring unknown parameters: textIgnoring unknown parameters: text
p3=ggplot(data=NULL,aes(x=srt_filter_cc@meta.data$cKit,y=srt_filter_cc@meta.data$Sca1,col=LPP))+
geom_point(alpha=0.5,size=1)+
scale_color_manual(values=c("grey70","red"))+
labs(x="cKit",y="Sca1",col="cluster")+
theme_bw()
p4=ggplot(data=NULL,aes(x=srt_filter_cc@meta.data$CD135,y=srt_filter_cc@meta.data$CD127,col=LPP))+
geom_point(alpha=0.5,size=1)+
scale_color_manual(values=c("grey70","red"))+
labs(x="CD135",y="CD127",col="cluster")+
theme_bw()
plot_grid(p1, p2, p3, p4,ncol=2)

LPP_cells = srt_filter_cc@meta.data$Dach1GFP < Dach1_thr & srt_filter_cc@meta.data$CD135 > CD135_hi_thr
CD135pp_cells = srt_filter_cc@meta.data$CD135 > CD135_very_hi_thr
LMPP_cells = srt_filter_cc@meta.data$CD135 > CD135_hi_thr
LPP_ident = srt_filter_cc@active.ident[LPP_cells]
CD135pp_ident = srt_filter_cc@active.ident[CD135pp_cells]
LMPP_ident = srt_filter_cc@active.ident[LMPP_cells]
srt_filter_cc$CD135pp=CD135pp_cells
srt_filter_cc$LPP=LPP_cells
prop.table(table(CD135pp_ident))
CD135pp_ident
0 1 2 3 4 5 6 7 8
0.060 0.096 0.156 0.236 0.376 0.020 0.020 0.036 0.000
prop.table(table(LPP_ident))
LPP_ident
0 1 2 3 4 5 6 7 8
0.02139037 0.04278075 0.18181818 0.18181818 0.47593583 0.01604278 0.04278075 0.03743316 0.00000000
prop.table(table(LMPP_ident))
LMPP_ident
0 1 2 3 4 5 6 7 8
0.137362637 0.122710623 0.205128205 0.194139194 0.190476190 0.058608059 0.043956044 0.045787546 0.001831502
ident_df = data.frame(
proportions = c(unname(prop.table(table(CD135pp_ident))), unname(prop.table(table(LPP_ident))), unname(prop.table(table(LMPP_ident)))),
clusters= as.factor(c(0:8,0:8,0:8)),
gate=c(rep("CD135pp",9),rep("LPP",9),rep("LMPP",9)))
ggplot(data=ident_df,aes(x=clusters,y=proportions,fill=gate))+
geom_bar(stat="identity",position="dodge" )+
theme_bw()

srt_filter_LPP = srt_filter_cc
Idents(srt_filter_LPP) = as.character(LPP_cells)
srt_filter_CD135pp = srt_filter_cc
Idents(srt_filter_CD135pp) = as.character(CD135pp_cells)
srt_filter_LPP.markers <- FindAllMarkers(srt_filter_LPP, logfc.threshold = 0.1,only.pos = TRUE,verbose=FALSE)
top10 <- srt_filter_LPP.markers %>% group_by(cluster) %>% top_n(n = 10, wt = avg_logFC)
DoHeatmap(srt_filter_LPP, features = top10$gene)

srt_filter_CD135pp.markers <- FindAllMarkers(srt_filter_CD135pp, logfc.threshold = 0.1,only.pos = TRUE,verbose=FALSE)
top10 <- srt_filter_CD135pp.markers %>% group_by(cluster) %>% top_n(n = 10, wt = avg_logFC)
DoHeatmap(srt_filter_CD135pp, features = top10$gene)

save.image("~/Dropbox/research/Dach1_paper/NN126/NN126_Seurat_cc_removel.RData")
singleR
top.n = 25
singleR_score = readRDS("~/Dropbox/research/Dach1_paper/NN126/singleR_score.Rds")
singleR_score = singleR_score[rownames(singleR_score) %in% colnames(srt_filter_cc),]
singleR_score = singleR_score[colnames(srt_filter_cc),]
m = apply(t(scale(t(singleR_score))),2,max)
thres = sort(m,decreasing=TRUE)[min(top.n+1,length(m))]
mmax = rowMaxs(singleR_score)
mmin = rowMins(singleR_score)
singleR_score = (singleR_score-mmin)/(mmax-mmin)
singleR_score = singleR_score^3
singleR_score_raw = singleR_score
#singleR_score = singleR_score[,m>thres]
singleR_score = singleR_score[,grepl("Stem cells",colnames(singleR_score))]
singleR_score_r = singleR_score[order(srt_filter_cc$integrated_snn_res.1.2),]
colo = col9
names(colo) = levels(srt_filter_cc$integrated_snn_res.1.2)
pheatmap::pheatmap(singleR_score_r,annotation_row=srt_filter_cc@meta.data[,c("seurat_clusters","Dach1GFP","CD150","CD135")],show_rownames=FALSE,cluster_rows = FALSE, annotation_colors=
list(seurat_clusters=colo,
Dach1GFP=c("dodgerblue2","white", "firebrick2"),
CD150=c("dodgerblue2","white", "firebrick2"),
CD135=c("dodgerblue2","white", "firebrick2")))

pheatmap::pheatmap(singleR_score_r,annotation_row=srt_filter_cc@meta.data[,c("seurat_clusters","Dach1GFP","CD150","CD135")],show_rownames=FALSE,cluster_rows = TRUE, annotation_colors=
list(seurat_clusters=colo,
Dach1GFP=c("dodgerblue2","white", "firebrick2"),
CD150=c("dodgerblue2","white", "firebrick2"),
CD135=c("dodgerblue2","white", "firebrick2")))

corr = apply(singleR_score_raw, 2, function(x){cor(x, srt_filter_cc$Dach1GFP,method="spearman")})
ord = order(corr,decreasing = TRUE)
singleR_score_r = singleR_score_raw[,c(ord[1:5],ord[(length(ord)-3):length(ord)])]
pheatmap::pheatmap(singleR_score_r,annotation_row=srt_filter_cc@meta.data[,c("seurat_clusters","Dach1GFP","CD150","CD135")],show_rownames=FALSE, annotation_colors=
list(seurat_clusters=colo,
Dach1GFP=c("dodgerblue2","white", "firebrick2"),
CD150=c("dodgerblue2","white", "firebrick2"),
CD135=c("dodgerblue2","white", "firebrick2")))

LS0tCnRpdGxlOiAiTk4xMjYgU2V1cmF0IHJlbW92ZSBjZWxsIGN5Y2xlIgpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sKLS0tCgpgYGB7cn0KbGlicmFyeShzY1BpcGUpCmxpYnJhcnkoc2NhdGVyKQpsaWJyYXJ5KHNjcmFuKQpsaWJyYXJ5KGdncGxvdDIpCmxpYnJhcnkoU2V1cmF0KQpsaWJyYXJ5KGNvd3Bsb3QpCmxpYnJhcnkoc2N0cmFuc2Zvcm0pCmxpYnJhcnkoZHBseXIpCmxpYnJhcnkocmVhZHIpCmxpYnJhcnkoZ2dyZXBlbCkKbGlicmFyeShSQ29sb3JCcmV3ZXIpCmdldFBhbGV0dGUgPSBjb2xvclJhbXBQYWxldHRlKGJyZXdlci5wYWwoOSwgIlNldDEiKSkKY29sOSA9IGdldFBhbGV0dGUoOSkKdHR0ID0gY29sOVs1XQpjb2w5WzVdID0gY29sOVsxXQpjb2w5WzFdID0gdHR0CmBgYAoKYGBge3J9CmxvYWQoIn4vRHJvcGJveC9yZXNlYXJjaC9EYWNoMV9wYXBlci9OTjEyNi9OTjEyNl9TZXVyYXRfYW5hbHlzaXMuUkRhdGEiKQpgYGAKCmBgYHtyfQpzLmdlbmVzIDwtIHRvbG93ZXIoY2MuZ2VuZXMkcy5nZW5lcykKZzJtLmdlbmVzIDwtIHRvbG93ZXIoY2MuZ2VuZXMkZzJtLmdlbmVzKQpzaW1wbGVDYXAgPC0gZnVuY3Rpb24oeCkgewogIHBhc3RlKHRvdXBwZXIoc3Vic3RyaW5nKHgsIDEsMSkpLCBzdWJzdHJpbmcoeCwgMiksCiAgICAgIHNlcD0iIikKfQpzLmdlbmVzID0gc2ltcGxlQ2FwKHMuZ2VuZXMpCmcybS5nZW5lcyA9IHNpbXBsZUNhcChnMm0uZ2VuZXMpCmBgYAoKYGBge3J9CnNydF9maWx0ZXJfY2MgPSBzcnRfY29tYmluZV9maWx0ZXIKc3J0X2ZpbHRlcl9jYyA8LSBDZWxsQ3ljbGVTY29yaW5nKHNydF9maWx0ZXJfY2MsIHMuZmVhdHVyZXMgPSBzLmdlbmVzLCBnMm0uZmVhdHVyZXMgPSBnMm0uZ2VuZXMsIHNldC5pZGVudCA9IEZBTFNFKQpoZWFkKHNydF9maWx0ZXJfY2NbW11dKQpgYGAKCmBgYHtyfQpSaWRnZVBsb3Qoc3J0X2ZpbHRlcl9jYywgZmVhdHVyZXMgPSBjKCJQY25hIiwgIlRvcDJhIiwgIk1jbTYiLCAiTWtpNjciKSwgbmNvbCA9IDIsY29scz1nZXRQYWxldHRlKDcpKQpgYGAKCmBgYHtyfQpEaW1QbG90KHNydF9maWx0ZXJfY2MsIHJlZHVjdGlvbiA9ICJ1bWFwIiwgZ3JvdXAuYnkgPSAiUGhhc2UiKQpgYGAKCgpgYGB7cn0Kc3J0X2ZpbHRlcl9jYyA8LSBTY2FsZURhdGEoc3J0X2ZpbHRlcl9jYywgdmFycy50by5yZWdyZXNzID0gYygiUy5TY29yZSIsICJHMk0uU2NvcmUiKSwgZmVhdHVyZXMgPSByb3duYW1lcyhzcnRfZmlsdGVyX2NjKSx2ZXJib3NlID0gRkFMU0UpCmBgYAoKYGBge3Isd2FybmluZz1GQUxTRSxtZXNzYWdlPUZBTFNFLHJlc3VsdHM9J2hpZGUnfQpzcnRfZmlsdGVyX2NjIDwtIFJ1blBDQShvYmplY3QgPSBzcnRfZmlsdGVyX2NjLCB2ZXJib3NlID0gRkFMU0UpCnNydF9maWx0ZXJfY2MgPC0gUnVuVU1BUChvYmplY3QgPSBzcnRfZmlsdGVyX2NjLCBkaW1zID0gMToxNSwgdmVyYm9zZSA9IEZBTFNFKQpzcnRfZmlsdGVyX2NjIDwtIEZpbmROZWlnaGJvcnMob2JqZWN0ID0gc3J0X2ZpbHRlcl9jYywgay5wYXJhbT0xMCwgZGltcyA9IDE6MTUsIHZlcmJvc2UgPSBGQUxTRSkKc3J0X2ZpbHRlcl9jYyA8LSBGaW5kQ2x1c3RlcnMob2JqZWN0ID0gc3J0X2ZpbHRlcl9jYywgdmVyYm9zZSA9IEZBTFNFLHJlc29sdXRpb24gPSAxLjIpCiMgVmlzdWFsaXphdGlvbgpwMSA8LSBEaW1QbG90KHNydF9maWx0ZXJfY2MsIHJlZHVjdGlvbiA9ICJ1bWFwIiwgZ3JvdXAuYnkgPSAiUGhhc2UiKQpwMiA8LSBEaW1QbG90KHNydF9maWx0ZXJfY2MsIHJlZHVjdGlvbiA9ICJ1bWFwIiwgbGFiZWwgPSBUUlVFLCBjb2xzPWNvbDkpCmBgYAoKYGBge3IsZmlnLndpZHRoPTEwLGZpZy5oZWlnaHQ9NX0KcGxvdF9ncmlkKHAxLCBwMikKYGBgCgoKYGBge3IsZmlnLmhlaWdodD0xMCxmaWcud2lkdGg9MTd9CnNydF9maWx0ZXJfY2MubWFya2VycyA8LSBGaW5kQWxsTWFya2VycyhzcnRfZmlsdGVyX2NjLCBsb2dmYy50aHJlc2hvbGQgPSAwLjEsb25seS5wb3MgPSBUUlVFLHZlcmJvc2U9RkFMU0UpCnRvcDEwIDwtIHNydF9maWx0ZXJfY2MubWFya2VycyAlPiUgZ3JvdXBfYnkoY2x1c3RlcikgJT4lIHRvcF9uKG4gPSAxMCwgd3QgPSBhdmdfbG9nRkMpCkRvSGVhdG1hcChzcnRfZmlsdGVyX2NjLCBmZWF0dXJlcyA9IHRvcDEwJGdlbmUpICMgY2Fubm90IGNoYW5nZSBjb2xvciBvZiB0aGUgY29sb3IgYmFyCmBgYAoKCmBgYHtyLGZpZy5oZWlnaHQ9NyxmaWcud2lkdGg9N30KVmxuUGxvdChvYmplY3QgPSBzcnRfZmlsdGVyX2NjLCBmZWF0dXJlcz0gYygiRGFjaDFHRlAiLCJDRDE1MCIsIkNEMTM1IiwiQ0QxMjciLCJjS2l0IiksIGNvbHM9Y29sOSwgbmNvbD0yLHB0LnNpemU9MC4xKQpgYGAKCgpgYGB7cixmaWcuaGVpZ2h0PTgsZmlnLndpZHRoPTEwfQpGZWF0dXJlUGxvdChvYmplY3QgPSBzcnRfZmlsdGVyX2NjLCBjb2xzID1yZXYocmFpbmJvdyg1KSlbMjo1XSxmZWF0dXJlcyA9YygiRGFjaDFHRlAiLCJDRDExYiIsIkNEMTUwIiwiQ0QxMjciLCJjS2l0IiwiQ0QxMzUiLCJTY2ExIiwiUEkiKSwgcHQuc2l6ZSA9MSkKYGBgCgpgYGB7cixmaWcud2lkdGg9OS41LGZpZy5oZWlnaHQ9OH0KcDE9Z2dwbG90KGRhdGE9TlVMTCxhZXMoeD1zcnRfZmlsdGVyX2NjQG1ldGEuZGF0YSRDRDEzNSx5PXNydF9maWx0ZXJfY2NAbWV0YS5kYXRhJENEMTUwLGNvbD1zcnRfZmlsdGVyX2NjQGFjdGl2ZS5pZGVudCkpKwogIGdlb21fcG9pbnQoYWxwaGE9MC43LHNpemU9MS41KSsKICBsYWJzKHg9IkNEMTM1Iix5PSJDRDE1MCIsY29sPSJjbHVzdGVyIikrCiAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcz1jb2w5KSsKICB0aGVtZV9idygpCnAyPWdncGxvdChkYXRhPU5VTEwsYWVzKHg9c3J0X2ZpbHRlcl9jY0BtZXRhLmRhdGEkRGFjaDFHRlAseT1zcnRfZmlsdGVyX2NjQG1ldGEuZGF0YSRDRDEzNSxjb2w9c3J0X2ZpbHRlcl9jY0BhY3RpdmUuaWRlbnQpKSsKICBnZW9tX3BvaW50KGFscGhhPTAuNyxzaXplPTEuNSkrCiAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcz1jb2w5KSsKICBsYWJzKHg9IkRhY2gxR0ZQIix5PSJDRDEzNSIsY29sPSJjbHVzdGVyIikrCiAgdGhlbWVfYncoKQoKcDM9Z2dwbG90KGRhdGE9TlVMTCxhZXMoeD1zcnRfZmlsdGVyX2NjQG1ldGEuZGF0YSRjS2l0LHk9c3J0X2ZpbHRlcl9jY0BtZXRhLmRhdGEkU2NhMSxjb2w9c3J0X2ZpbHRlcl9jY0BhY3RpdmUuaWRlbnQpKSsKICBnZW9tX3BvaW50KGFscGhhPTAuNyxzaXplPTEuNSkrCiAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcz1jb2w5KSsKICBsYWJzKHg9ImNLaXQiLHk9IlNjYTEiLGNvbD0iY2x1c3RlciIpKwogIHRoZW1lX2J3KCkKCnA0PWdncGxvdChkYXRhPU5VTEwsYWVzKHg9c3J0X2ZpbHRlcl9jY0BtZXRhLmRhdGEkQ0QxMzUseT1zcnRfZmlsdGVyX2NjQG1ldGEuZGF0YSRDRDEyNyxjb2w9c3J0X2ZpbHRlcl9jY0BhY3RpdmUuaWRlbnQpKSsKICBnZW9tX3BvaW50KGFscGhhPTAuNyxzaXplPTEuNSkrCiAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcz1jb2w5KSsKICBsYWJzKHg9IkNEMTM1Iix5PSJDRDEyNyIsY29sPSJjbHVzdGVyIikrCiAgdGhlbWVfYncoKQoKcGxvdF9ncmlkKHAxLCBwMiwgcDMsIHA0LG5jb2w9MikKYGBgCgojIHRyYWplY3RvcnkKCmBgYHtyfQojIEJpb2NNYW5hZ2VyOjppbnN0YWxsKCJzdXByYUhleCIpCiMgQmlvY01hbmFnZXI6Omluc3RhbGwoIlJncmFwaHZpeiIpCgpsaWJyYXJ5KFhHUikKeCA9IHhDb252ZXJ0ZXIoc3J0X2ZpbHRlcl9jY0BncmFwaHMkaW50ZWdyYXRlZF9zbm4sIGZyb20gPSAiZGdDTWF0cml4IiwKdG8gPSJpZ3JhcGgiLHZlcmJvc2UgPSBGQUxTRSkKYGBgCgpgYGB7cn0KZ2dwbG90Q29sb3VycyA8LSBmdW5jdGlvbihuID0gNiwgaCA9IGMoMCwgMzYwKSArIDE1KXsKICBpZiAoKGRpZmYoaCkgJSUgMzYwKSA8IDEpIGhbMl0gPC0gaFsyXSAtIDM2MC9uCiAgaGNsKGggPSAoc2VxKGhbMV0sIGhbMl0sIGxlbmd0aCA9IG4pKSwgYyA9IDEwMCwgbCA9IDY1KQp9CmBgYAoKYGBge3IsZmlnLndpZHRoPTksZmlnLmhlaWdodD05fQpsaWJyYXJ5KGlncmFwaCkKc2V0LnNlZWQoMTk5MTA2MDMpCmwgPC0gbGF5b3V0X3dpdGhfZnIoeCxkaW09MixuaXRlcj0yMDAwLHN0YXJ0LnRlbXA9NTAwKQpwbG90KHgsIGxheW91dD1sLCB2ZXJ0ZXgubGFiZWw9TkEsdmVydGV4LnNpemU9Myx2ZXJ0ZXguY29sb3I9c3J0X2ZpbHRlcl9jYyRpbnRlZ3JhdGVkX3Nubl9yZXMuMS4yLHBhbGV0dGU9Y29sOSkKYGBgCgpgYGB7cn0KbGlicmFyeShzbGluZ3Nob3QpCnNscyA9IHNsaW5nc2hvdChsLCBjbHVzdGVyTGFiZWxzID0gc3J0X2ZpbHRlcl9jYyRpbnRlZ3JhdGVkX3Nubl9yZXMuMS4yLHN0YXJ0LmNsdXM9MSkKCnBsb3QobCwgY29sPWNvbDlbc3J0X2ZpbHRlcl9jYyRpbnRlZ3JhdGVkX3Nubl9yZXMuMS4yXSwgcGNoPTE2LCBhc3AgPSAxKQpsaW5lcyhzbHMsIGx3ZD0yLCBjb2w9J2JsYWNrJykKYGBgCgpgYGB7cn0KdG9wMiA8LSBzcnRfZmlsdGVyX2NjLm1hcmtlcnMgJT4lIGdyb3VwX2J5KGNsdXN0ZXIpICU+JSB0b3BfbihuID0gMiwgd3QgPSBhdmdfbG9nRkMpCiNEb3RQbG90KHNydF9maWx0ZXJfY2MsIGZlYXR1cmVzID0gYyh0b3AyJGdlbmUsIkNEMTM1IiwiRGFjaDFHRlAiKSkgKyBSb3RhdGVkQXhpcygpCmBgYAoKIyBMUFAgTE1QUAoKYGBge3IsZmlnLndpZHRoPTEwLGZpZy5oZWlnaHQ9OH0KCkxQUCA9IHJlcChGQUxTRSxsZW5ndGgoc3J0X2ZpbHRlcl9jY0BhY3RpdmUuaWRlbnQpKQpMUFBbc3J0X2ZpbHRlcl9jY0BhY3RpdmUuaWRlbnQ9PTRdID0gVFJVRQoKQ0QxMzVfaGlfdGhyID0gIDMuCkNEMTM1X3ZlcnlfaGlfdGhyID0gIDMuNQpEYWNoMV90aHIgPSAyLjgKCgoKcDE9Z2dwbG90KGRhdGE9TlVMTCxhZXMoeD1zcnRfZmlsdGVyX2NjQG1ldGEuZGF0YSRDRDEzNSx5PXNydF9maWx0ZXJfY2NAbWV0YS5kYXRhJENEMTUwLGNvbD1MUFApKSsKICBnZW9tX3BvaW50KGFscGhhPTAuNSxzaXplPTEpKwogIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IENEMTM1X3ZlcnlfaGlfdGhyLGxpbmV0eXBlPSJkb3R0ZWQiKSsKICBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSBDRDEzNV9oaV90aHIsbGluZXR5cGU9ImRvdHRlZCIpKwogIGdlb21fdGV4dChhZXMoeD1DRDEzNV9oaV90aHIsIGxhYmVsPSJMTVBQXG4iLCB5PTIuNyksIGNvbG91cj0iYmx1ZSIsIGFuZ2xlPTkwLCB0ZXh0PWVsZW1lbnRfdGV4dChzaXplPTExKSkrCiAgZ2VvbV90ZXh0KGFlcyh4PUNEMTM1X3ZlcnlfaGlfdGhyLCBsYWJlbD0iQ0QxMzUrK1xuIiwgeT0yLjcpLCBjb2xvdXI9ImJsdWUiLCBhbmdsZT05MCwgdGV4dD1lbGVtZW50X3RleHQoc2l6ZT0xMSkpKwogIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXM9YygiZ3JleTcwIiwicmVkIikpKwogIGxhYnMoeD0iQ0QxMzUiLHk9IkNEMTUwIixjb2w9ImNsdXN0ZXIiKSsKICB0aGVtZV9idygpCnAyPWdncGxvdChkYXRhPU5VTEwsYWVzKHg9c3J0X2ZpbHRlcl9jY0BtZXRhLmRhdGEkRGFjaDFHRlAseT1zcnRfZmlsdGVyX2NjQG1ldGEuZGF0YSRDRDEzNSxjb2w9TFBQKSkrCiAgZ2VvbV9wb2ludChhbHBoYT0wLjUsc2l6ZT0xKSsKICBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSBEYWNoMV90aHIsbGluZXR5cGU9ImRvdHRlZCIpKwogIGdlb21fdGV4dChhZXMoeD1EYWNoMV90aHIsIGxhYmVsPSJEYWNoMS1cbiIsIHk9My41KSwgY29sb3VyPSJibHVlIiwgYW5nbGU9OTAsIHRleHQ9ZWxlbWVudF90ZXh0KHNpemU9MTEpKSsKICBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSBDRDEzNV9oaV90aHIsbGluZXR5cGU9ImRvdHRlZCIpKwogIGdlb21fdGV4dChhZXMoeT1DRDEzNV9oaV90aHIsIGxhYmVsPSJMTVBQXG4iLCB4PTIuNSksIGNvbG91cj0iYmx1ZSIsIHRleHQ9ZWxlbWVudF90ZXh0KHNpemU9MTEpKSsKICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzPWMoImdyZXk3MCIsInJlZCIpKSsKICBsYWJzKHg9IkRhY2gxR0ZQIix5PSJDRDEzNSIsY29sPSJjbHVzdGVyIikrCiAgdGhlbWVfYncoKQoKcDM9Z2dwbG90KGRhdGE9TlVMTCxhZXMoeD1zcnRfZmlsdGVyX2NjQG1ldGEuZGF0YSRjS2l0LHk9c3J0X2ZpbHRlcl9jY0BtZXRhLmRhdGEkU2NhMSxjb2w9TFBQKSkrCiAgZ2VvbV9wb2ludChhbHBoYT0wLjUsc2l6ZT0xKSsKICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzPWMoImdyZXk3MCIsInJlZCIpKSsKICBsYWJzKHg9ImNLaXQiLHk9IlNjYTEiLGNvbD0iY2x1c3RlciIpKwogIHRoZW1lX2J3KCkKCnA0PWdncGxvdChkYXRhPU5VTEwsYWVzKHg9c3J0X2ZpbHRlcl9jY0BtZXRhLmRhdGEkQ0QxMzUseT1zcnRfZmlsdGVyX2NjQG1ldGEuZGF0YSRDRDEyNyxjb2w9TFBQKSkrCiAgZ2VvbV9wb2ludChhbHBoYT0wLjUsc2l6ZT0xKSsKICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzPWMoImdyZXk3MCIsInJlZCIpKSsKICBsYWJzKHg9IkNEMTM1Iix5PSJDRDEyNyIsY29sPSJjbHVzdGVyIikrCiAgdGhlbWVfYncoKQoKcGxvdF9ncmlkKHAxLCBwMiwgcDMsIHA0LG5jb2w9MikKYGBgCgpgYGB7cn0KTFBQX2NlbGxzID0gc3J0X2ZpbHRlcl9jY0BtZXRhLmRhdGEkRGFjaDFHRlAgPCBEYWNoMV90aHIgJiBzcnRfZmlsdGVyX2NjQG1ldGEuZGF0YSRDRDEzNSA+IENEMTM1X2hpX3RocgpDRDEzNXBwX2NlbGxzID0gIHNydF9maWx0ZXJfY2NAbWV0YS5kYXRhJENEMTM1ID4gQ0QxMzVfdmVyeV9oaV90aHIKTE1QUF9jZWxscyA9ICBzcnRfZmlsdGVyX2NjQG1ldGEuZGF0YSRDRDEzNSA+IENEMTM1X2hpX3RocgoKTFBQX2lkZW50ID0gc3J0X2ZpbHRlcl9jY0BhY3RpdmUuaWRlbnRbTFBQX2NlbGxzXQpDRDEzNXBwX2lkZW50ID0gc3J0X2ZpbHRlcl9jY0BhY3RpdmUuaWRlbnRbQ0QxMzVwcF9jZWxsc10KTE1QUF9pZGVudCA9IHNydF9maWx0ZXJfY2NAYWN0aXZlLmlkZW50W0xNUFBfY2VsbHNdCmBgYAoKYGBge3J9CnNydF9maWx0ZXJfY2MkQ0QxMzVwcD1DRDEzNXBwX2NlbGxzCnNydF9maWx0ZXJfY2MkTFBQPUxQUF9jZWxscwpgYGAKCmBgYHtyfQpwcm9wLnRhYmxlKHRhYmxlKENEMTM1cHBfaWRlbnQpKQpwcm9wLnRhYmxlKHRhYmxlKExQUF9pZGVudCkpCnByb3AudGFibGUodGFibGUoTE1QUF9pZGVudCkpCmBgYAoKYGBge3J9CmlkZW50X2RmID0gZGF0YS5mcmFtZSgKICBwcm9wb3J0aW9ucyA9IGModW5uYW1lKHByb3AudGFibGUodGFibGUoQ0QxMzVwcF9pZGVudCkpKSwgdW5uYW1lKHByb3AudGFibGUodGFibGUoTFBQX2lkZW50KSkpLCB1bm5hbWUocHJvcC50YWJsZSh0YWJsZShMTVBQX2lkZW50KSkpKSwKICBjbHVzdGVycz0gYXMuZmFjdG9yKGMoMDo4LDA6OCwwOjgpKSwKICBnYXRlPWMocmVwKCJDRDEzNXBwIiw5KSxyZXAoIkxQUCIsOSkscmVwKCJMTVBQIiw5KSkpCgpnZ3Bsb3QoZGF0YT1pZGVudF9kZixhZXMoeD1jbHVzdGVycyx5PXByb3BvcnRpb25zLGZpbGw9Z2F0ZSkpKwogIGdlb21fYmFyKHN0YXQ9ImlkZW50aXR5Iixwb3NpdGlvbj0iZG9kZ2UiICkrCiAgdGhlbWVfYncoKQoKYGBgCgoKYGBge3J9CnNydF9maWx0ZXJfTFBQID0gc3J0X2ZpbHRlcl9jYwpJZGVudHMoc3J0X2ZpbHRlcl9MUFApID0gYXMuY2hhcmFjdGVyKExQUF9jZWxscykKc3J0X2ZpbHRlcl9DRDEzNXBwID0gc3J0X2ZpbHRlcl9jYwpJZGVudHMoc3J0X2ZpbHRlcl9DRDEzNXBwKSA9IGFzLmNoYXJhY3RlcihDRDEzNXBwX2NlbGxzKQpgYGAKCgpgYGB7cn0Kc3J0X2ZpbHRlcl9MUFAubWFya2VycyA8LSBGaW5kQWxsTWFya2VycyhzcnRfZmlsdGVyX0xQUCwgbG9nZmMudGhyZXNob2xkID0gMC4xLG9ubHkucG9zID0gVFJVRSx2ZXJib3NlPUZBTFNFKQp0b3AxMCA8LSBzcnRfZmlsdGVyX0xQUC5tYXJrZXJzICU+JSBncm91cF9ieShjbHVzdGVyKSAlPiUgdG9wX24obiA9IDEwLCB3dCA9IGF2Z19sb2dGQykKRG9IZWF0bWFwKHNydF9maWx0ZXJfTFBQLCBmZWF0dXJlcyA9IHRvcDEwJGdlbmUpCmBgYAoKYGBge3J9CnNydF9maWx0ZXJfQ0QxMzVwcC5tYXJrZXJzIDwtIEZpbmRBbGxNYXJrZXJzKHNydF9maWx0ZXJfQ0QxMzVwcCwgbG9nZmMudGhyZXNob2xkID0gMC4xLG9ubHkucG9zID0gVFJVRSx2ZXJib3NlPUZBTFNFKQp0b3AxMCA8LSBzcnRfZmlsdGVyX0NEMTM1cHAubWFya2VycyAlPiUgZ3JvdXBfYnkoY2x1c3RlcikgJT4lIHRvcF9uKG4gPSAxMCwgd3QgPSBhdmdfbG9nRkMpCkRvSGVhdG1hcChzcnRfZmlsdGVyX0NEMTM1cHAsIGZlYXR1cmVzID0gdG9wMTAkZ2VuZSkKYGBgCgoKYGBge3J9CnNhdmUuaW1hZ2UoIn4vRHJvcGJveC9yZXNlYXJjaC9EYWNoMV9wYXBlci9OTjEyNi9OTjEyNl9TZXVyYXRfY2NfcmVtb3ZlbC5SRGF0YSIpCmBgYAoKIyBzaW5nbGVSCgpgYGB7cixmaWcud2lkdGg9NyxmaWcuaGVpZ2h0PTEwfQp0b3AubiA9IDI1CnNpbmdsZVJfc2NvcmUgPSByZWFkUkRTKCJ+L0Ryb3Bib3gvcmVzZWFyY2gvRGFjaDFfcGFwZXIvTk4xMjYvc2luZ2xlUl9zY29yZS5SZHMiKQoKc2luZ2xlUl9zY29yZSA9IHNpbmdsZVJfc2NvcmVbcm93bmFtZXMoc2luZ2xlUl9zY29yZSkgJWluJSBjb2xuYW1lcyhzcnRfZmlsdGVyX2NjKSxdCnNpbmdsZVJfc2NvcmUgPSBzaW5nbGVSX3Njb3JlW2NvbG5hbWVzKHNydF9maWx0ZXJfY2MpLF0KbSA9IGFwcGx5KHQoc2NhbGUodChzaW5nbGVSX3Njb3JlKSkpLDIsbWF4KQp0aHJlcyA9IHNvcnQobSxkZWNyZWFzaW5nPVRSVUUpW21pbih0b3AubisxLGxlbmd0aChtKSldCgptbWF4ID0gcm93TWF4cyhzaW5nbGVSX3Njb3JlKQptbWluID0gcm93TWlucyhzaW5nbGVSX3Njb3JlKQpzaW5nbGVSX3Njb3JlID0gKHNpbmdsZVJfc2NvcmUtbW1pbikvKG1tYXgtbW1pbikKc2luZ2xlUl9zY29yZSA9IHNpbmdsZVJfc2NvcmVeMwpzaW5nbGVSX3Njb3JlX3JhdyA9IHNpbmdsZVJfc2NvcmUKCiNzaW5nbGVSX3Njb3JlID0gc2luZ2xlUl9zY29yZVssbT50aHJlc10Kc2luZ2xlUl9zY29yZSA9IHNpbmdsZVJfc2NvcmVbLGdyZXBsKCJTdGVtIGNlbGxzIixjb2xuYW1lcyhzaW5nbGVSX3Njb3JlKSldCnNpbmdsZVJfc2NvcmVfciA9IHNpbmdsZVJfc2NvcmVbb3JkZXIoc3J0X2ZpbHRlcl9jYyRpbnRlZ3JhdGVkX3Nubl9yZXMuMS4yKSxdCmNvbG8gPSBjb2w5Cm5hbWVzKGNvbG8pID0gbGV2ZWxzKHNydF9maWx0ZXJfY2MkaW50ZWdyYXRlZF9zbm5fcmVzLjEuMikKcGhlYXRtYXA6OnBoZWF0bWFwKHNpbmdsZVJfc2NvcmVfcixhbm5vdGF0aW9uX3Jvdz1zcnRfZmlsdGVyX2NjQG1ldGEuZGF0YVssYygic2V1cmF0X2NsdXN0ZXJzIiwiRGFjaDFHRlAiLCJDRDE1MCIsIkNEMTM1IildLHNob3dfcm93bmFtZXM9RkFMU0UsY2x1c3Rlcl9yb3dzID0gRkFMU0UsIGFubm90YXRpb25fY29sb3JzPQogICAgICAgICAgICAgICAgICAgICBsaXN0KHNldXJhdF9jbHVzdGVycz1jb2xvLAogICAgICAgICAgICAgICAgICAgICAgICAgIERhY2gxR0ZQPWMoImRvZGdlcmJsdWUyIiwid2hpdGUiLCAiZmlyZWJyaWNrMiIpLAogICAgICAgICAgICAgICAgICAgICAgICAgIENEMTUwPWMoImRvZGdlcmJsdWUyIiwid2hpdGUiLCAiZmlyZWJyaWNrMiIpLCAKICAgICAgICAgICAgICAgICAgICAgICAgICBDRDEzNT1jKCJkb2RnZXJibHVlMiIsIndoaXRlIiwgImZpcmVicmljazIiKSkpCmBgYAoKYGBge3IsZmlnLndpZHRoPTcsZmlnLmhlaWdodD0xMH0KcGhlYXRtYXA6OnBoZWF0bWFwKHNpbmdsZVJfc2NvcmVfcixhbm5vdGF0aW9uX3Jvdz1zcnRfZmlsdGVyX2NjQG1ldGEuZGF0YVssYygic2V1cmF0X2NsdXN0ZXJzIiwiRGFjaDFHRlAiLCJDRDE1MCIsIkNEMTM1IildLHNob3dfcm93bmFtZXM9RkFMU0UsY2x1c3Rlcl9yb3dzID0gVFJVRSwgYW5ub3RhdGlvbl9jb2xvcnM9CiAgICAgICAgICAgICAgICAgICAgIGxpc3Qoc2V1cmF0X2NsdXN0ZXJzPWNvbG8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgRGFjaDFHRlA9YygiZG9kZ2VyYmx1ZTIiLCJ3aGl0ZSIsICJmaXJlYnJpY2syIiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgQ0QxNTA9YygiZG9kZ2VyYmx1ZTIiLCJ3aGl0ZSIsICJmaXJlYnJpY2syIiksIAogICAgICAgICAgICAgICAgICAgICAgICAgIENEMTM1PWMoImRvZGdlcmJsdWUyIiwid2hpdGUiLCAiZmlyZWJyaWNrMiIpKSkKYGBgCgoKYGBge3IsZmlnLndpZHRoPTcsZmlnLmhlaWdodD0xMH0KY29yciA9IGFwcGx5KHNpbmdsZVJfc2NvcmVfcmF3LCAyLCBmdW5jdGlvbih4KXtjb3IoeCwgc3J0X2ZpbHRlcl9jYyREYWNoMUdGUCxtZXRob2Q9InNwZWFybWFuIil9KQpvcmQgPSBvcmRlcihjb3JyLGRlY3JlYXNpbmcgPSBUUlVFKQpzaW5nbGVSX3Njb3JlX3IgPSBzaW5nbGVSX3Njb3JlX3Jhd1ssYyhvcmRbMTo1XSxvcmRbKGxlbmd0aChvcmQpLTMpOmxlbmd0aChvcmQpXSldCnBoZWF0bWFwOjpwaGVhdG1hcChzaW5nbGVSX3Njb3JlX3IsYW5ub3RhdGlvbl9yb3c9c3J0X2ZpbHRlcl9jY0BtZXRhLmRhdGFbLGMoInNldXJhdF9jbHVzdGVycyIsIkRhY2gxR0ZQIiwiQ0QxNTAiLCJDRDEzNSIpXSxzaG93X3Jvd25hbWVzPUZBTFNFLCBhbm5vdGF0aW9uX2NvbG9ycz0KICAgICAgICAgICAgICAgICAgICAgbGlzdChzZXVyYXRfY2x1c3RlcnM9Y29sbywKICAgICAgICAgICAgICAgICAgICAgICAgICBEYWNoMUdGUD1jKCJkb2RnZXJibHVlMiIsIndoaXRlIiwgImZpcmVicmljazIiKSwKICAgICAgICAgICAgICAgICAgICAgICAgICBDRDE1MD1jKCJkb2RnZXJibHVlMiIsIndoaXRlIiwgImZpcmVicmljazIiKSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgQ0QxMzU9YygiZG9kZ2VyYmx1ZTIiLCJ3aGl0ZSIsICJmaXJlYnJpY2syIikpKQpgYGAKCgpgYGB7cn0KCmBgYAoK